﻿using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Base
{
    public partial class Base_DeviceBusiness : BaseBusiness<Base_Device>, IBase_DeviceBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IOperatorDept _odept;
        readonly IOperatorDept _odepts;

        public Base_DeviceBusiness(IDbAccessor db, IOperator @operator, IOperatorDept @odept, IOperatorDept @odepts)
            : base(db)
        {
            _operator = @operator;
            _odept = @odept;
            _odepts = @odepts;
        }

        #region 外部接口

        /*
        * 开发人：朱庆龙
        * 提交日期：2022-02-22 9:28
        * 修改内容：展示生产设备信息
        * 上传SVN：是
        */
        public async Task<PageResult<Base_DeviceDTO>> GetDataListAsync(PageInput<DeviceConditionDTO> input)
        {
            var search = input.Search;
            Expression<Func<Base_Device, Base_EnumItem, PB_ProcecureSub, Base_Department, Base_Department, Base_Department, Base_User, Base_DeviceDTO>> select = (a, b, c, d, e, f, g) => new Base_DeviceDTO
            {
                TypeName = b.Name,
                ProcecureMainName = c.Name,
                FackName = d.Name,
                WorkShopName = e.Name,
                DeptName = f.Name,
                UserName = g.RealName,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_EnumItem>() on a.Type equals b.Code into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcecureSubId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_Department>() on a.DeptId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<Base_Department>() on a.WorkShopId equals e.Id into ae
                    from e in ae.DefaultIfEmpty()
                    join f in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals f.Id into af
                    from f in af.DefaultIfEmpty()
                    join g in Db.GetIQueryable<Base_User>() on a.PersonId equals g.Id into ag
                    from g in ag.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d, e, f, g);
            if (!search.Keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.Keyword}%";
                q = q.Where(x =>
                      EF.Functions.Like(x.Name, keyword)
                      || EF.Functions.Like(x.Code, keyword)
              );
            }
            if (!search.DeviceType.IsNullOrEmpty())
            {
                q = q.Where(x => x.Type == search.DeviceType);
            }

            if (!search.DeviceSpec.IsNullOrEmpty())
            {
                q = q.Where(x => x.Spec.Contains(search.DeviceSpec));
            }
            if (!search.SubId.IsNullOrEmpty())
            {
                q = q.Where(x => x.ProcecureSubId == search.SubId);
            }
            //生产设备权限
            q = q.Where(m => _operator.Property.DeptIds.Contains(m.DeptId));
            return await q.GetPageResultAsync(input);
        }

        public async Task<Base_Device> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        /// <summary>
        /// 递归查找公司下所有的仓库
        /// </summary>
        /// <param name="deptId">组织Id</param>
        /// <param name="deptlist">是仓库的集合</param>
        /// <param name="Departmentdata">组织数据</param>
        /// <returns></returns>
        private List<string> GetDeptIteminfo(string deptId, List<string> deptlist, List<Base_Department> Departmentdata,int i)
        {
            List<Base_Department> dlist = new List<Base_Department>();
            //特殊处理
            if (i == 0)
            {
                dlist = Departmentdata.Where(x => x.Id == deptId).ToList();
            }
            else {
                dlist = Departmentdata.Where(x => x.ParentId == deptId).ToList();
            }
             
            foreach (var item in dlist)
            {
                deptlist.Add(item.Id);
                GetDeptIteminfo(item.Id, deptlist, Departmentdata, ++i);
            }
            return deptlist;
        }
        /// <summary>
        /// 方法重载
        /// </summary>
        /// <param name="deptId"></param>
        /// <param name="deptlist"></param>
        /// <param name="Departmentdata"></param>
        /// <returns></returns>
        private List<string> GetDeptItem(string deptId, List<string> deptlist, List<Base_Department> Departmentdata)
        {
        
              var  dlist = Departmentdata.Where(x => x.ParentId == deptId).ToList();
            foreach (var item in dlist)
            {
                deptlist.Add(item.Id);
                GetDeptItem(item.Id, deptlist, Departmentdata);
            }
            return deptlist;
        }
        [DataAddLog(UserLogType.设备管理, "Name", "设备管理")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "设备编号" })]
        public async Task AddDataAsync(Base_Device data)
        {
            data.QrCode = h_Device + "," + data.DeptId + "," + data.CreateTime.ToString("yyMMdd") + "," + data.Id;
            await InsertAsync(data);
        }

        [DataEditLog(UserLogType.设备管理, "Name", "设备管理")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "设备编号" })]
        public async Task UpdateDataAsync(Base_Device data)
        {
            data.QrCode = h_Device + "," + data.DeptId + "," + data.CreateTime.ToString("yyMMdd") + "," + data.Id;
            await UpdateAsync(data);
        }

        [DataDeleteLog(UserLogType.设备管理, "Name", "设备管理")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            List<PB_CirculationBill> CirculationBillList = await Db.GetIQueryable<PB_CirculationBill>().Where(x => ids.Contains(x.DeviceId)).ToListAsync();
            List<PB_JobBooking> JobBookingList = await Db.GetIQueryable<PB_JobBooking>().Where(x => ids.Contains(x.DeviceId)).ToListAsync();
            if (CirculationBillList.Count > 0 || JobBookingList.Count > 0)
            {
                throw new BusException("已被引用不能删除");
            }
            await DeleteAsync(ids);
        }

        public async Task<List<Base_DeviceDTO>> Selectid(string id)
        {
            Expression<Func<Base_Device, Base_EnumItem, PB_ProcecureSub,Base_Department, Base_DeviceDTO>> select = (a, b, c,d) => new Base_DeviceDTO
            {
                TypeName = b.Name,
                ProcecureMainName = c.Name,
                WorkShopName=d.Name,

            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_EnumItem>() on a.Type equals b.Code into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcecureSubId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_Department>() on a.WorkShopId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    select @select.Invoke(a, b, c,d);
            string[] arr = id.Split(',');
            List<string> List = new List<string>();
            foreach (var item in arr) {
                List.Add(item);
            }
            q = q.Where(x => List.Contains(x.Id));
            var res =await q.ToListAsync();
            return res;

        }
        /// <summary>
        /// 获取当前登录人下法人的部门
        /// </summary>
        /// <returns></returns>
        public async Task<List<Base_Department>> GetDetpListAsync()
        {
            List<Base_Department> listdata = new List<Base_Department>();
            var detpdata = await _odept.GetOperatorDept();
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            if (detpdata.DeptType != 8)
            {
                var deptlist = Departmentdata.Where(x => x.ParentId == detpdata.DetpId).ToList();
                List<string> liststr = new List<string>();
                foreach (var item in deptlist)
                {
                    liststr.Add(item.Id);
                    GetDeptItem(item.Id, liststr, Departmentdata);
                }
                listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 6).ToList();
            }
            else
            {
                listdata = Departmentdata.Where(x => x.Id == detpdata.DetpId).ToList();
            }
            return listdata;
        }

        public  async Task<List<Base_Department>> GetDetpListAsyncWorkShop()
        {
            var detpdata = await _odept.GetOperatorGongChang(_operator.Property?.DepartmentId);
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == detpdata.DetpId).ToList();
            List<string> liststr = new List<string>();
        
            foreach (var item in deptlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, Departmentdata);
            }
            List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && (x.Type == 3 || x.Type == 8)).ToList();
            listdata.OrderByDescending(x=>x.Name);
            return listdata;
        }

        public async Task<List<Base_Department>> GetDetpListAsyncFatoc()
        {
            //获取登录人的部门信息
            var deptdata1 = await _odept.GetOperatorDeptType();
            var detpdata = await _odept.GetOperatorDept();
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            
                var deptlist = Departmentdata.Where(x => x.Id == detpdata.DetpId).ToList();
                
            List<string> liststr = new List<string>();
            //foreach (var item in deptlist)
            //{
            //    liststr.Add(item.Id);
            //    GetDeptItem(item.Id, liststr, Departmentdata);
            //}
            for (int i = 0; i < deptlist.Count; i++)
            {
                liststr.Add(deptlist[i].Id);
                GetDeptIteminfo(deptlist[i].Id, liststr, Departmentdata,i);
            }
            //listdata.Add(detpdata.DetpId);
            if (deptdata1.DeptType == 8)
            {
                List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 8 && x.SupplierId == deptdata1.SupplierId).ToList();
                return listdata;
            }
            else
            {
                List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 1 ).ToList();
                return listdata;
            }
            
        }

        public  async Task<List<Base_Department>> GetDetpListAsyncFatoc7()
        {
            var detpdata = await _odept.GetOperatorDeptType();
            var depdad = await _odepts.GetOperatorGongChang(detpdata.DetpId);
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.Id == depdad.DetpId).ToList();
            List<string> liststr = new List<string>();
            //foreach (var item in deptlist)
            //{
            //    liststr.Add(item.Id);
            //    GetDeptItem(item.Id, liststr, Departmentdata);
            //}
            for (int i = 0; i < deptlist.Count; i++)
            {
                liststr.Add(deptlist[i].Id);
                GetDeptIteminfo(deptlist[i].Id, liststr, Departmentdata, i);
            }
            //listdata.Add(detpdata.DetpId);
            List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 7).ToList();
            return listdata;
        }
        public IQueryable<T> GetQueryable<T>() where T : class, new()
        {
            return Db.GetIQueryable<T>();
        }
        public  async Task AddUserExlAsync(List<Base_Device> list)
        {
            await Db.InsertAsync<Base_Device>(list);
        }

        public  async Task<List<Base_Department>> GetDetpListAsyncBumen()
        {
            var detpdata = await _odept.GetOperatorDeptGongchang();
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == detpdata.DetpId).ToList();
            List<string> liststr = new List<string>();

            foreach (var item in deptlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, Departmentdata);
            }
            List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 3).ToList();
            return listdata;
        }

        public async Task<List<Base_Department>> GetDetpListAsyncBumenis()
        {
            var detpdata = await _odept.GetOperatorDeptBumenId();
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == detpdata.DetpId).ToList();
            List<string> liststr = new List<string>();

            foreach (var item in deptlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, Departmentdata);
            }
            List<Base_Department> listdata = Departmentdata.Where(x => liststr.Contains(x.Id) && x.Type == 3).ToList();
            return listdata;
        }

        #endregion

        #region 私有成员

        #endregion
    }
}